/**
 * 类型索引文件生成工具（ESM版本）
 * 
 * 本脚本用于自动生成index.ts文件，它将导出auto/types目录下所有的类型定义
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// 获取当前文件的路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 定义类型目录
const typesDir = path.resolve(__dirname, '../types');

// 日志工具
const logger = {
    log: (message) => {
        console.log(`[INFO] ${message}`);
    },
    error: (message, error) => {
        console.error(`[ERROR] ${message}`);
        if (error) console.error(error);
    }
};

/**
 * 从表名获取接口名
 * @param {string} tableName 表名
 * @returns {string} 接口名称
 */
function getInterfaceNameFromTableName(tableName) {
    // 将表名转换为驼峰式，并添加I前缀
    return 'I' + tableName.split('_').map(part =>
        part.charAt(0).toUpperCase() + part.slice(1)
    ).join('');
}

/**
 * 生成类型索引文件
 * @returns {string|null} 索引文件路径或null（失败时）
 */
function generateTypeIndexFile() {
    logger.log('开始生成类型索引文件...');

    // 获取所有在types目录下存在对应.ts文件的表
    const allTypeFiles = [];
    try {
        const files = fs.readdirSync(typesDir);
        // 获取所有.ts文件（排除index.ts）
        const tsFiles = files.filter(file => file.endsWith('.ts') && file !== 'index.ts');
        logger.log(`在目录 ${typesDir} 中找到 ${tsFiles.length} 个TypeScript文件`);

        // 对于每个ts文件，创建表项
        tsFiles.forEach(file => {
            const tableName = file.replace('.ts', '');
            allTypeFiles.push({
                tableName,
                tsFilePath: path.join(typesDir, file),
                hasTsFile: true
            });
        });
    } catch (error) {
        logger.error(`读取类型目录失败: ${error.message}`, error);
        return null;
    }

    if (allTypeFiles.length === 0) {
        logger.log('没有找到TypeScript接口文件，跳过生成索引文件');
        return null;
    }

    // 生成索引文件内容
    let indexContent = `/**
 * 自动生成的数据表接口类型定义索引
 * 
 * 本文件导出所有由数据表生成的TypeScript接口定义
 * 使用时可以通过此文件统一导入所需的接口类型
 * 
 * 生成时间: ${new Date().toISOString()}
 */

/**
 * 自动生成的数据库表对应TypeScript类型定义
 * 
 * 此文件由生成工具自动创建，请勿手动修改
 * 如需修改表结构，请通过数据库变更并重新生成
 */

// API通用类型定义
/**
 * HTTP响应基础接口
 */
export interface IHttpResponse<T = any> {
  /**
   * 状态码
   */
  code: number;
  
  /**
   * 响应消息
   */
  msg: string;
  
  /**
   * 响应数据
   */
  data: T;
  
  /**
   * 请求是否成功
   */
  success: boolean;
  
  /**
   * 时间戳
   */
  timestamp?: number;
}

/**
 * 通用查询参数接口
 */
export interface IQueryParams {
  /**
   * 当前页码
   */
  page: number;
  
  /**
   * 每页数据量
   */
  pageSize: number;
  
  /**
   * 排序配置
   */
  orderBy?: {
    /**
     * 排序字段
     */
    field: string;
    
    /**
     * 排序方向
     */
    order: 'asc' | 'desc';
  };
  
  /**
   * 查询条件
   */
  condition?: Array<{
    /**
     * 字段名
     */
    field: string;
    
    /**
     * 查询值
     */
    value: any;
    
    /**
     * 比较操作符
     */
    compare: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'in' | 'nin';
  }>;
}

/**
 * 分页响应接口
 */
export interface IPaginationResult<T = any> {
  /**
   * 总记录数
   */
  total: number;
  
  /**
   * 当前页码
   */
  current: number;
  
  /**
   * 每页数据量
   */
  pageSize: number;
  
  /**
   * 总页数
   */
  pages: number;
  
  /**
   * 数据列表
   */
  records: T[];
}

// 导出查询结果类型
export type FindListResult<T> = IPaginationResult<T>;

// 导出所有表接口
`;

    // 对于每个表，添加export语句
    // 按照字母顺序排序表名，使导出更有组织性
    allTypeFiles.sort((a, b) => a.tableName.localeCompare(b.tableName));

    // 记录找到的接口数量
    logger.log(`准备导出 ${allTypeFiles.length} 个TypeScript接口`);

    // 导出所有表的接口
    allTypeFiles.forEach(table => {
        const interfaceName = getInterfaceNameFromTableName(table.tableName);
        indexContent += `export { ${interfaceName} } from './${table.tableName}';\n`;
    });

    // 写入索引文件
    const indexFilePath = path.join(typesDir, 'index.ts');
    try {
        fs.writeFileSync(indexFilePath, indexContent);
        logger.log(`类型索引文件已保存到: ${indexFilePath}`);
        logger.log(`成功导出 ${allTypeFiles.length} 个接口到索引文件`);
        return indexFilePath;
    } catch (error) {
        logger.error(`保存类型索引文件失败: ${error.message}`, error);
        return null;
    }
}

// 执行生成函数
generateTypeIndexFile();

// 导出函数以便其他模块使用
export default generateTypeIndexFile; 